// Code file original author: Martin Lapierre, http://devinstinct.com

using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace Microsoft.Practices.EnterpriseLibrary.Validation.Tests.Validators
{
	/// <summary>
	/// Tests <see cref="TypeValidator"/>.
	/// </summary>
	[TestClass]
	public class TypeValidatorFixture
	{
		[TestMethod]
		public void ReturnsSuccessForSameType()
		{
			TypeValidator<string> validator = new TypeValidator<string>();
			ValidationResults validationResults = validator.Validate("test");

			Assert.IsTrue(validationResults.IsValid);
		}

		[TestMethod]
		public void NegatedReturnsFailureForSameType()
		{
			TypeValidator<string> validator = new TypeValidator<string>(null, null, true);
			ValidationResults validationResults = validator.Validate("test");

			Assert.IsFalse(validationResults.IsValid);
		}

		[TestMethod]
		public void ReturnsFailureForDifferentTypes()
		{
			TypeValidator<string> validator = new TypeValidator<string>();
			ValidationResults validationResults = validator.Validate(123);

			Assert.IsFalse(validationResults.IsValid);
		}

		[TestMethod]
		public void NegatedReturnsSuccessForDifferentTypes()
		{
			TypeValidator<string> validator = new TypeValidator<string>(null, null, true);
			ValidationResults validationResults = validator.Validate(123);

			Assert.IsTrue(validationResults.IsValid);
		}

		[TestMethod]
		public void ReturnsSuccessForInheritedTypes()
		{
			TypeValidator<TestTargetA> validator = new TypeValidator<TestTargetA>();
			ValidationResults validationResults = validator.Validate(new TestTargetB());

			Assert.IsTrue(validationResults.IsValid);
		}

		[TestMethod]
		public void NegatedReturnsFailureForInheritedTypes()
		{
			TypeValidator<TestTargetA> validator = new TypeValidator<TestTargetA>(null, null, true);
			ValidationResults validationResults = validator.Validate(new TestTargetB());

			Assert.IsFalse(validationResults.IsValid);
		}

		[TestMethod]
		public void ReturnsFailureForDerivedTypes()
		{
			TypeValidator<TestTargetB> validator = new TypeValidator<TestTargetB>();
			ValidationResults validationResults = validator.Validate(new TestTargetA());

			Assert.IsFalse(validationResults.IsValid);
		}

		[TestMethod]
		public void NegatedReturnsSuccessForDerivedTypes()
		{
			TypeValidator<TestTargetB> validator = new TypeValidator<TestTargetB>(null, null, true);
			ValidationResults validationResults = validator.Validate(new TestTargetA());

			Assert.IsTrue(validationResults.IsValid);
		}

		[TestMethod]
		public void ReturnsFailureForNull()
		{
			TypeValidator<string> validator = new TypeValidator<string>();
			ValidationResults validationResults = validator.Validate(null);

			Assert.IsFalse(validationResults.IsValid);
		}

		[TestMethod]
		public void NegatedReturnsSuccessForNull()
		{
			TypeValidator<string> validator = new TypeValidator<string>(null, null, true);
			ValidationResults validationResults = validator.Validate(null);

			Assert.IsTrue(validationResults.IsValid);
		}

		[TestMethod]
		public void ReturnsSuccessForZero()
		{
			TypeValidator<int> validator = new TypeValidator<int>();
			ValidationResults validationResults = validator.Validate(0);

			Assert.IsTrue(validationResults.IsValid);
		}

		[TestMethod]
		public void NegatedReturnsFailureForZero()
		{
			TypeValidator<int> validator = new TypeValidator<int>(null, null, true);
			ValidationResults validationResults = validator.Validate(0);

			Assert.IsFalse(validationResults.IsValid);
		}

		/// <summary>
		/// Test target A for this fixture.
		/// </summary>
		public class TestTargetA
		{
		}

		/// <summary>
		/// Test target B for this fixture.
		/// </summary>
		public class TestTargetB
			 : TestTargetA
		{
		}
	}
}
